#pragma once
#include <iostream>
#include <string>

namespace component {

class LidarPoint {
 public:
  float angle_;  // [degree]
  float dist_;   // [cm]
  LidarPoint() : angle_(0), dist_(0) {}
  LidarPoint(float angle, float dist) : angle_(angle), dist_(dist) {}
};

class Velocity {
 public:
  float vx; /* x轴移动速度 */
  float vy; /* y轴移动速度 */
  float wz; /* z轴转动速度 */

  Velocity() : vx(0), vy(0), wz(0) {}
  Velocity(float x, float y, float z) : vx(x), vy(y), wz(z) {}
};

enum class NmeaType {
  kUNKNOWN,
  kTXT,
  kGGA,
  kRMC,
};

std::string NmeaTypeToString(NmeaType type);

class Nmea {
 public:
  NmeaType type; /* NMEA 种类 */
  float lon;     /* longtitude 经度 */
  float la;      /* latitude 纬度 */

  Nmea() : type(NmeaType::kUNKNOWN), lon(0), la(0) {}
  Nmea(float lon, float lat) : type(NmeaType::kUNKNOWN), lon(lon), la(lat) {}
};

enum class RoboExpression {
  kOK,
  kFILE_ERROR,
  kFRAME_ERROR,
  kTRANS_ERROR,
  kRECV_ERROR,
  kOTHER_ERROR,
};

class Expression {
 private:
  RoboExpression exp_;

 public:
  Expression();
  Expression(RoboExpression exp);
  Expression& operator=(RoboExpression exp);
  Expression& operator()(RoboExpression exp);
  bool operator==(RoboExpression exp);

  std::string What();
};

}  // namespace component

using Expr = component::Expression;
using Error = component::RoboExpression;
